﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Rhino.Geometry;

namespace Import_glTF
{
    internal class BufferReader : BinaryReader
    {
        public BufferReader(string strFile) : base(File.OpenRead(strFile)) { }
        public BufferReader(Stream input) : base(input) { }
        public Point3d[] ReadPositions(Gltf.GltfAccessor accessor, Gltf.GltfBufferView bufferView)
        {
            ulong byteOffset = (ulong)accessor.ByteOffset;
            int count = accessor.Count;
            byteOffset += bufferView.ByteOffset;
            byte[] buffer = new byte[count * 12];
            BaseStream.Seek((long)byteOffset, SeekOrigin.Begin);
            BaseStream.Read(buffer,0, (int)bufferView.ByteLength);
            Point3d[] positions = new Point3d[count];
            for (int i = 0; i < count; i++)
            {
                int offset = i * 12;
                positions[i].X = BitConverter.ToSingle(buffer, offset);
                positions[i].Y = BitConverter.ToSingle(buffer, offset + 4);
                positions[i].Z = BitConverter.ToSingle(buffer, offset + 8);
            }
            return positions;
        }
        public Vector3f[] ReadNormals(Gltf.GltfAccessor accessor, Gltf.GltfBufferView bufferView)
        {
            ulong byteOffset = (ulong)accessor.ByteOffset;
            int count = accessor.Count;
            byteOffset += bufferView.ByteOffset;
            byte[] buffer = new byte[count * 12];
            BaseStream.Seek((long)byteOffset, SeekOrigin.Begin);
            BaseStream.Read(buffer, 0, (int)bufferView.ByteLength);
            Vector3f[] normals = new Vector3f[count];
            for (int i = 0; i < count; i++)
            {
                int offset = i * 12;
                normals[i].X = BitConverter.ToSingle(buffer, offset);
                normals[i].Y = BitConverter.ToSingle(buffer, offset + 4);
                normals[i].Z = BitConverter.ToSingle(buffer, offset + 8);
            }
            return normals;
        }
        public Point2f[] ReadTexcoords(Gltf.GltfAccessor accessor, Gltf.GltfBufferView bufferView)
        {
            ulong byteOffset = (ulong)accessor.ByteOffset;
            int count = accessor.Count;
            byteOffset += bufferView.ByteOffset;
            byte[] buffer = new byte[count * 8];
            BaseStream.Seek((long)byteOffset, SeekOrigin.Begin);
            BaseStream.Read(buffer, 0, (int)bufferView.ByteLength);
            Point2f[] texcoords = new Point2f[count];
            for (int i = 0; i < count; i++)
            {
                int offset = i * 8;
                texcoords[i].X = BitConverter.ToSingle(buffer, offset);
                texcoords[i].Y = BitConverter.ToSingle(buffer, offset + 4);
            }
            return texcoords;
        }
        public uint[] ReadIndices(Gltf.GltfAccessor accessor, Gltf.GltfBufferView bufferView)
        {
            ulong byteOffset = (ulong)accessor.ByteOffset;
            int count = accessor.Count;
            byteOffset += bufferView.ByteOffset;
            byte[] buffer = new byte[count * 4];
            BaseStream.Seek((long)byteOffset, SeekOrigin.Begin);
            BaseStream.Read(buffer, 0, (int)bufferView.ByteLength);
            uint[] indices = new uint[count];
            for (int i = 0; i < count; i++)
            {
                int offset = i * 4;
                indices[i]=BitConverter.ToUInt32(buffer,offset);
            }
            return indices;
        }
    }
}
